
#ifndef MATRIX3_H
#define MATRIX3_H

#include <memory>

/*
 * [ A_11 A_12 A_13 ]
 * [ A_21 A_22 A_23 ]
 * [ A_31 A_32 A_33 ]
 */
template <typename Real>
class Matrix3 {
public:
	enum ElementIndex { 
		A_11, A_12, A_13,
		A_21, A_22, A_23,
		A_31, A_32, A_33,
		COMPONENT_COUNT
	};

	Matrix3();
	virtual ~Matrix3();

	bool set(ElementIndex i, Real value);
	bool set(unsigned int i, unsigned int j, Real value);

	Real& operator () (unsigned int i, unsigned int j);
	Real& operator [] (ElementIndex i);

protected:
	Real data[COMPONENT_COUNT];
	const unsigned int n = COMPONENT_COUNT * COMPONENT_COUNT;
};

template<typename Real>
inline Matrix3<Real>::Matrix3() {
	std::memset(this->data, 0, COMPONENT_COUNT * sizeof(Real));
}

template<typename Real>
inline Matrix3<Real>::~Matrix3() {}

template<typename Real>
inline bool Matrix3<Real>::set(ElementIndex i, Real value) {
	if ( e == COMPONENTS ) return false;
	this->data[i] = value;
	return true;
}

template<typename Real>
inline bool Matrix3<Real>::set(unsigned int i, unsigned int j, Real value) {
	if ( i * this->n + j >= (this->n * this->n) ) return false;
	this->data[i * this->n + j] = value;
	return false;
}

template<typename Real>
inline Real & Matrix3<Real>::operator () (unsigned int i, unsigned int j) {
	if ( data[i * this->n + j] >= (this->n * this->n) ) return this->data[0];
	return this->data[i * this->n + j];
}

template<typename Real>
inline Real & Matrix3<Real>::operator [] (ElementIndex i) {
	return this->data[i];
}

typedef Matrix3<float> Matrix3f;
typedef Matrix3<double> Matrix3d;
typedef Matrix3<int> Matrix3i;

#endif
